home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / PPCpack / libs.txt < prev    next >
Text File  |  1998-04-16  |  8KB  |  333 lines

  1. E) PPC Shared Libraries
  2. =======================
  3.  
  4. This article handles:
  5.  
  6. 1) Using PPC Shared Libraries
  7. 2) Creating PPC Shared Libraries
  8.  
  9. It assumes you already read c.txt and mixed.txt.
  10.  
  11. 1) Using PPC Shared Libraries
  12. -----------------------------
  13.  
  14. Well, basically it is the same like using a 68k Shared Libraries.
  15. Internally WarpOS Shared Libraries have exactly the same format
  16. like 68k Shared Libraries. Only that some entries on the jumptable
  17. point to PPC Code. Basically they are all Mixed Binary. At least
  18. the Library-Init and -Expunge are done in 68k.
  19.  
  20. There are three types of PPC Shared Libraries:
  21.  
  22. A) 68k/PPC Mixed-Libs
  23. B) 68k/PPC Mixed-Fat-Libs
  24. C) PPC-Only Libs
  25.  
  26. An 68k/PPC Mixed-Lib is a library that has every of it's functions
  27. available for both 68k. Some (or all) of the functions are also available
  28. as special PPC Versions. The PPC-Versions have different offsets than the
  29. 68k-Versions. Only a PPC-System can use the PPC-Functions, but the library
  30. can also be used on a 68k System, if only the 68k functions are used.
  31. rtgmaster.library is an example of Type A).
  32.  
  33. + no Contextswitches needed
  34. + only one Lib for both 68k and PPC functions
  35. - to compile 68k+PPC Versions of a program constructs like
  36.  
  37. #ifdef __PPC__
  38. CopyRtgBlitPPC(...);
  39. #else
  40. CopyRtgBlit(...);
  41. #endif
  42.  
  43. have to be used.
  44.  
  45. A 68k/PPC Mixed-Fat-Lib implements every function only once. All functions
  46. use a 68k Header. This header finds out, if a PPC is present. If yes,
  47. it uses the PPC-optimized version, else the 68k version.
  48.  
  49. + only one Lib for both 68k and PPC functions
  50. + no complicated constructs needed
  51. - Every function uses two Contextswitches (one from PPC to 68k to
  52.   run the header, one from 68k to PPC to run the optimized function).
  53.  
  54. This type should only be used (if used at all !!!) for functions that
  55. take VERY long (for a MPEG Lib or such...)
  56.  
  57. PPC-Only Libs run only on PPC-Systems. There might exist an 68k version
  58. of the library with a different name.
  59.  
  60. + no complicated constructs needed
  61. + no Contextswitches needed
  62. - two libraries, one for PPC, one for 68k
  63.  
  64. To use a PPC Library you would do:
  65.  
  66. - include the clib-include-file
  67. - Call the function
  68.  
  69. For libraries not included in ppcamiga.lib (all OS Libs and rtgmaster
  70. are included there) you have additionally to create a PPC-Stub-File,
  71. like described in c.txt, and link together with this. You only need
  72. the PPC-Stub-File for 68k functions in the Library (if it is a
  73. PPC-Only-Lib you do not need it). You don't include any pragmas.
  74.  
  75. That is ALL about this theme.
  76.  
  77. 2) Creating PPC-Shared-Libraries
  78.  
  79. Principially you have to do like described in mixed.txt, creating a Mixed
  80. Binary (Even a PPC-Only Lib is a mixed Binary, as the Library Init is always 68k).
  81.  
  82. You specify the Library-Init like this:
  83.  
  84. void INIT_0_InitTheLib(register __a6 struct MyLibBase *base)
  85. {
  86.  MyLibBase=base;
  87.  // Rest of the Init
  88. }
  89.  
  90. You specify the Library-Expunge like:
  91.  
  92. void EXIT_0_ExitTheLib(register __a6 struct MyLibBase *base)
  93. {
  94.  base=MyLibBase;
  95. }
  96.  
  97. The structure MyLibBase has to be defined before, of course. After the includes
  98. you have to specify:
  99.  
  100. struct MyLibBase
  101. {
  102.  struct Library mlb_MyLibBase;
  103.  // Rest of data you want to store
  104. };
  105.  
  106. struct MyLibBase *MyLibBase;
  107.  
  108. #pragma libbase MyLibBase
  109.  
  110. If you want your library also to work on a plain 68k system, you add:
  111.  
  112. struct Library *PowerPCBase;
  113.  
  114. void INIT_0_PowerPCBase(void)
  115. {
  116.  PowerPCBase=OpenLibrary("powerpc.library",7);
  117. }
  118.  
  119. void EXIT_0_PowerPCBase(void)
  120. {
  121.  if (PowerPCBase) CloseLibrary(PowerPCBase);
  122. }
  123.  
  124. Now you can check the variable PowerPCBase in your functions to find out, if
  125. this is a PPC or a 68k system. (if the variable is 0, it is a 68k System).
  126.  
  127. Note: If you would open powerpc.library inside the Libinit of your library,
  128. your library would fail to open if powerpc.library fails to open. Because of
  129. this, we had to do it in the init of powerpc.library itselves...
  130.  
  131. Take this also a general rule: if stuff in the LibInit fails to open => the
  132. library fails to open.
  133.  
  134. Principially the rest of the Library is just defining the Library functions, but
  135. i will explain it a bit more detailed:
  136.  
  137. You have to define the following files:
  138.  
  139. MyLib_protos.h
  140. MyLib_lib.fd
  141. MyLib.c
  142. MyLib_PPC.c
  143.  
  144. All works after the rules for Mixed Binaries.
  145.  
  146. - MyLib.c contains the LibInit and the 68k functions of your library (if it has any).
  147. - MyLib_PPC.c contains the PPC functions of your library
  148. - MyLib_lib.fd contains the FD Stuff for the library
  149. - MyLib_protos.h contains the Prototypes for the library
  150.  
  151. MyLib_protos.h
  152. --------------
  153.  
  154. A Proto-File for a PPC Shared library looks like (Example) :
  155.  
  156. #ifndef MYLIB_PROTOS_H
  157. #define MYLIB_PROTOS_H
  158.  
  159. #ifndef __PPC__
  160.  
  161. #ifdef __cplusplus
  162. extern "C" {
  163. #endif
  164.  
  165. void test68k(int bla);
  166. int  foo68k(int bar);
  167.  
  168. #ifdef __cplusplus
  169. };
  170. #endif
  171.  
  172. #else
  173.  
  174. extern "AmigaLib" MyLibBase
  175. {
  176.  // The numbers are the function offsets in the jumptable !!!
  177.  void testPPC_(struct Library *,int)=-42;
  178.  int  fooPPC_(struct Library *,int)=-48;
  179. }
  180.  
  181. __inline void testPPC(int bla)
  182. {
  183.  extern struct Library *MyLibBase;
  184.  testPPC_(MyLibBase,bla);
  185. }
  186.  
  187. __inline int fooPPC(int bar)
  188. {
  189.  extern struct Library *MyLibBase;
  190.  return fooPPC_(MyLibBase,bar);
  191. }
  192.  
  193. #endif
  194. #endif
  195.  
  196. Note, that you have to create a PPC-Stub, like explained in c.txt, if you
  197. want to use the 68k functions inside a PPC Source (inside a 68k source
  198. this is not needed, of course).
  199.  
  200. MyLib_lib.fd:
  201. -------------
  202.  
  203. FDs for PPC Shared Libraries are defined exactly like FDs for 68k-Libraries.
  204. The only difference is, that NO PARAMETERS ARE GIVEN FOR PPC FUNCTIONS, EVEN
  205. IF THEY HAVE SOME.
  206.  
  207. Example (no complete FD File, only two example lines of a FD File...)
  208.  
  209. ; ...
  210. testfunc68k(bla)(d0)
  211. testfuncPPC()()
  212. ; ...
  213.  
  214. Both functions have one parameter, but the parameter of the PPC Function is not
  215. specified in the FD-File.
  216.  
  217. MyLib.c
  218. -------
  219.  
  220. Example:
  221.  
  222. #include <clib/exec_protos.h>
  223. #include <pragma/exec_lib.h>
  224. #include <exec/libraries.h>
  225.  
  226. struct MyLibBase
  227. {
  228.  struct Library mlb_MyLibBase;
  229.  // Rest of data you want to store
  230. };
  231.  
  232. struct MyLibBase *MyLibBase;
  233.  
  234. #pragma libbase MyLibBase
  235.  
  236. void INIT_0_InitTheLib(register __a6 struct MyLibBase *base)
  237. {
  238.  MyLibBase=base;
  239.  // Rest of the Init
  240. }
  241.  
  242. You specify the Library-Expunge like:
  243.  
  244. void EXIT_0_ExitTheLib(register __a6 struct MyLibBase *base)
  245. {
  246.  base=MyLibBase;
  247. }
  248.  
  249. If you want your library also to work on a plain 68k system, you add:
  250.  
  251. struct Library *PowerPCBase;
  252.  
  253. void INIT_0_PowerPCBase(void)
  254. {
  255.  PowerPCBase=OpenLibrary("powerpc.library",7);
  256. }
  257.  
  258. void EXIT_0_PowerPCBase(void)
  259. {
  260.  if (PowerPCBase) CloseLibrary(PowerPCBase);
  261. }
  262.  
  263. void test68k(register __d0 int bla)
  264. {
  265. }
  266.  
  267. int foo68k(register __d0 int bar)
  268. {
  269.  return 0;
  270. }
  271.  
  272. MyLib_PPC.c
  273. -----------
  274.  
  275. The most important additional thing to usual Mixed Binary Sources is, that all
  276. Library functions have to be specified with __saveds.
  277.  
  278. Example:
  279.  
  280. void __saveds testPPC(int bla)
  281. {
  282. }
  283.  
  284. int __saveds fooPPC(int bar)
  285. {
  286.  return 0;
  287. }
  288.  
  289. As you see, my example-library is a Type A) Library (PPC-Mixed...). You should now
  290. be able to create Libraries of all three types yourselves.
  291.  
  292. Note: After you compiled your library, you have to manually remove all PPC-Functions from
  293. the automatically generated MyLib_lib.h. This pragma-File has been generated
  294. from the FD-File, but pragma-Files are only for 68k. If you do not do this, you
  295. will get errors when using the Library.
  296.  
  297. Possible Problems:
  298.  
  299. - "I get illegal 24 Bit Relocation all the time"
  300.  
  301. Possible Reasons for this one:
  302.  
  303. - you forgot to set "Debuggable Code" for the first Compilation. Please change
  304.   the compiler options to Debugging Code and compile once more.
  305.  
  306. - You tried to call a 68k Assembler Function from the PPC Part. This can only
  307.   be done using a manual Context-Swtich. The Automatic Contextswitch only
  308.   handles functions written in C.
  309.  
  310. - you tried to call a function of MyLib.c that is specified with register
  311.   parameters. To fix this, simply define (Example):
  312.  
  313. In PPC Code:
  314.  
  315. //...
  316. test68k_Stack(bla);
  317. //...
  318.  
  319. In 68k Code:
  320.  
  321. void test68k_Stack(int bla)
  322. {
  323.  test68k(int bla);
  324. }
  325.  
  326. void test68k(register __d0 int bla)
  327. {
  328. }
  329.  
  330. This the automatic Contextswitch can handle. If you do not like this solution,
  331. use the manual Contextswitch or implement the 68k function in PPC Code.
  332.  
  333.